import { Db } from "../../main";
import { buildSession, Sort } from "../../utils/common";
import { ISession, ITogglePinSessionParams } from "../../types/session";
import { IMessage } from "../../types/message.ts";

// 合并session
export function MergeSession(localSession: ISession[], remoteMessage: IMessage[]): void {
  try {
    if (remoteMessage.length === 0) return;

    const remoteSessionMap: Record<string, IMessage[]> = {};
    for (const message of remoteMessage) {
      if (!remoteSessionMap[message.sessionId]) {
        remoteSessionMap[message.sessionId] = [message];
        continue;
      }
      Sort(remoteSessionMap[message.sessionId], message);
    }

    const localSessionMap = new Map<string, ISession>();
    for (const session of localSession) {
      localSessionMap.set(session.sessionId, session);
    }

    for (const [sessionId, messages] of Object.entries(remoteSessionMap)) {
      const latestMessage = messages[messages.length - 1];
      const session = buildSession(latestMessage);
      const unread = messages.length;
      const localSession = localSessionMap.get(sessionId);
      if (localSession && localSession.ownerId === latestMessage.toId) {
        UpdateSessionByField(sessionId, session.ownerId, {
          ...session,
          unread,
        });
        continue;
      }
      InsertSession(session, unread);
    }
  } catch (error) {
    console.error("MergeSession error:", error);
  }
}

// 插入session
export function InsertSession(session: Omit<ISession, "id">, unread: number = 0): boolean {
  try {
    const stmt = Db.prepare(`
      INSERT INTO session (ownerId, toId, content, sessionId,
                           chatType, sessionType, unread)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `);

    const result = stmt.run(
      session.ownerId,
      session.toId,
      session.content || "",
      session.sessionId,
      session.chatType,
      session.sessionType,
      unread,
    );
    return (result.lastInsertRowid as number) > 0;
  } catch (error) {
    console.error("InsertSession error:", error);
    return false;
  }
}

// 添加session记录
export function AddSession(session: ISession): ISession {
  try {
    const selectStmt = Db.prepare(`
      SELECT * FROM session
      WHERE sessionId = ? AND ownerId = ? AND isDel = 1
      LIMIT 1
    `);
    const existing = selectStmt.get(session.sessionId, session.ownerId) as ISession;
    if (existing) {
      const updateStmt = Db.prepare(`
        UPDATE session
        SET isDel = 0, updatedAt = (strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime'))
        WHERE id = ?
      `);
      updateStmt.run(existing.id);
      existing.isDel = 0;
      existing.updatedAt = new Date().toISOString();
      return existing;
    }
    InsertSession(session);
    return session;
  } catch (error) {
    console.error("AddSession error:", error);
    return session;
  }
}

// 获取用户session
export function GetSessionsByUser(ownerId: number): ISession[] {
  try {
    const query = `
      SELECT *
      FROM session
      WHERE ownerId = ? AND isDel = 0
      ORDER BY isPinned DESC, updatedAt DESC
    `;
    const params = [ownerId];
    return (Db.prepare(query).all(...params) as ISession[]) || [];
  } catch (error) {
    console.error("GetSessionsByUser error:", error);
    return [];
  }
}

// 更新session（按字段）
export function UpdateSessionByField(
  sessionId: string,
  ownerId: number,
  updates: Partial<Omit<ISession, "id" | "sessionId">>,
): boolean {
  try {
    const fields = [];
    const values = [];

    for (const [key, value] of Object.entries(updates)) {
      if (value !== undefined) {
        fields.push(`${key} = ?`);
        values.push(value);
      }
    }

    if (fields.length === 0) return false;

    const query = `
      UPDATE session
      SET ${fields.join(", ")},
          updatedAt = (strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime'))
      WHERE sessionId = ?
        AND ownerId = ?
    `;

    const result = Db.prepare(query).run(...values, sessionId, ownerId);
    return result.changes > 0;
  } catch (error) {
    console.error("UpdateSessionByField error:", error);
    return false;
  }
}

// 更新session（按会话对象）
export function UpdateSessionBySession(session: ISession, unreadIncrement: number = 1): boolean {
  try {
    const result = Db.prepare(
      `
        UPDATE session
        SET content = ?,
            sessionType = ?,
            unread = unread + ?,
            updatedAt = (strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime'))
        WHERE sessionId = ?
          AND ownerId = ?
      `,
    ).run(session.content, session.sessionType, unreadIncrement, session.sessionId, session.ownerId);
    return result.changes > 0;
  } catch (error) {
    console.error("UpdateSessionBySession error:", error);
    return false;
  }
}

// 更新或创建会话
export function UpdateOrCreateSession(session: ISession, unreadIncrement: number = 1): boolean {
  try {
    const existing = Db.prepare(
      `SELECT unread
       FROM session
       WHERE sessionId = ?
         AND ownerId = ?`,
    ).get(session.sessionId, session.ownerId);

    if (!existing) return InsertSession(session);

    return UpdateSessionBySession(session, unreadIncrement);
  } catch (error) {
    console.error("UpdateOrCreateSession error:", error);
    return false;
  }
}

// 传递sessionList
export function UpdateOrCreateSessionList(sessions: ISession[]): boolean {
  try {
    Db.transaction(() => {
      for (const session of sessions) {
        const existing = Db.prepare(
          `SELECT unread
           FROM session
           WHERE sessionId = ?
             AND ownerId = ?`,
        ).get(session.sessionId, session.ownerId);

        if (!existing) InsertSession(session);
        else UpdateSessionBySession(session);
      }
    })();
    return true;
  } catch (error) {
    console.error("UpdateOrCreateSessions error:", error);
    return false;
  }
}

// 处理未读消息
export function HandelUnread(sessionId: string, ownerId: number): boolean {
  try {
    const current = Db.prepare(
      `SELECT unread
       FROM session
       WHERE sessionId = ?
         AND ownerId = ?`,
    ).get(sessionId, ownerId) as ISession;

    if (current && current.unread === 0) {
      return true;
    }
    const result = Db.prepare(
      `
        UPDATE session
        SET unread = ?,
            updatedAt = CURRENT_TIMESTAMP
        WHERE sessionId = ?
          AND ownerId = ?
      `,
    ).run(0, sessionId, ownerId);

    return result.changes > 0;
  } catch (error) {
    console.error("HandelUnread error:", error);
    return false;
  }
}

// 置顶会话
export function TogglePinSession(params: ITogglePinSessionParams): boolean {
  try {
    const result = Db.prepare(
      `
        UPDATE session
        SET isPinned = ?
        WHERE sessionId = ?
          AND ownerId = ?
      `,
    ).run(params.pinState ? 1 : 0, params.sessionId, params.ownerId);

    return result.changes > 0;
  } catch (error) {
    console.error("TogglePinSession error:", error);
    return false;
  }
}

// 软删除会话
export function SoftDeleteSession(sessionId: string, ownerId: number): boolean {
  try {
    const result = Db.prepare(
      `
        UPDATE session
        SET isDel = 1
        WHERE sessionId = ?
          AND ownerId = ?
      `,
    ).run(sessionId, ownerId);
    return result.changes > 0;
  } catch (error) {
    console.error("SoftDeleteSession error:", error);
    return false;
  }
}
